#include"head.h"

int main(int argc, char *argv[])
{
    // ./00_client 192.168.72.128 12345
    // 客户端cd后ls打印之前的路径是应为cd /user1之后tlv.value被更新为/user1,每次打印内容是没有更新
    // tlv.value的内容导致重复打印（即使cd了一个不存在的目录也会更新tlv结构体,cd命令因该再）
    // 返回错误的值时候重新清空value,至于打印的歧义造成的影响暂时不需要改变
    char netip[]="172.21.76.123";
    char netport[] ="20001";

    //ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(netport));
    addr.sin_addr.s_addr = inet_addr(netip);
    int ret = connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");
    char c=' ';

    char buf[1024];//指令暂存
    char buf1[1024];//参数一
    int num = 0;//参数+指令个数
    int i = 0;//指针，在各缓冲区中的位置
    TLV* TLV_recv = (TLV*)malloc(sizeof(TLV));
    TLV* TLV_t = (TLV*)malloc(sizeof(TLV));
    if (TLV_t == NULL) {
        printf("error,create TLV\n");
        return -1;
    }

    while(1) {
        int success=0;
        while (1) {
            printf("请选择登录/注册,请摁n/y\n");
            success=0;//登录注册是否成功
            while ((c = getchar()) == '\n' || c == ' ');
            if (c == 'y' || c == 'Y') {
                printf("注册开始\n");
                register_user(sockfd,&success);
                if(success==1)
                    break;
            }
            else if (c == 'n' || c == 'N') {
                printf("登陆开始\n");
                signin_user(sockfd, &success);
                if(success==1)
                    break;
            }
            else {
                printf("error,请重试\n");
                while (getchar() != '\n');
            }
        }

        printf("success=%d\n",success);//登录注册成功，开始识别命令
       
        init_train(TLV_recv);//输入接收缓冲区，初始化
        init_train(TLV_t);
        int is_find_order = 0;

        while(1) {
            num=0; 
            printf("客户端开始处理命令——————————————————————————————\n");
            while (1) {
                i=0;
                memset(TLV_recv,0,sizeof(TLV));
            memset(TLV_t,0,sizeof(TLV));
                memset(buf, 0, sizeof(buf));
        memset(buf1, 0, sizeof(buf1));
                while (1) {//开头空格忽略
                    c = getchar();
                    if (c == '\n')
                        break;
                    else if (c != ' ' && c != '\n') {
                        num++;
                        buf[i] = c;
                        i++;
                        break;
                    }
                }
                if (c == '\n')
                    break;
                while ((c = getchar()) != '\n' && c != ' ' && i < 1023) {//第一个命令存入buf中
                    buf[i++] = c;
                }
                buf[i] = '\0';
                if (c == '\n')
                    break;
                i = 0;
                while (1) {//处理第1参数和命令间的空格
                    c = getchar();
                    if (c == '\n')
                        break;
                    else if (c != ' ' && c != '\n') {
                        num++;
                        buf1[i] = c;
                        i++;
                        break;
                    }
                }
                if (c == '\n')
                    break;
                while ((c = getchar()) != '\n' && c != ' ' && i < 1023) {
                    buf1[i++] = c;
                }
                buf1[i] = '\0';
                i=0;
                if (c == '\n')
                    break;//第1个参数结束
                while (1) {//第一个参数后处理
                    c = getchar();
                    if (c == '\n') {
                        break;
                    }
                    else if (c != ' ') {
                        num++;
                        break;
                    }
                }
                if (c == '\n')
                    break;
            }

            if (num > 2) {
                printf("error,参数错误\n");
                continue;
            }
            printf("buf=%s\n", buf);
            printf("buf1=%s\n", buf1);
            if (strcmp(buf, "cd") == 0 && num == 2) { //cd命令
                printf("传输命令cd,路径为%s,是否为绝对路径：%d\n", buf1, is_absolute_path(buf1));
                TLV_t->type = 0x01;
                TLV_t->seq = is_absolute_path(buf1);
                TLV_t->length = (uint32_t)strlen(buf1);
                strncpy(TLV_t->value, buf1, sizeof(TLV_t->value) - 1);
                TLV_t->value[sizeof(TLV_t->value) - 1] = '\0';
                printf("传输命令cd,路径为%s,传输长度为%d,i是否为绝对路径：%d\n", TLV_t->value, TLV_t->length, TLV_t->seq);
                sendTlv(sockfd,TLV_t);
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv->type==0xFF) {
                    printf("error,接收错误\n");
                } else {
                    printf("%s\n",TLV_recv->value);
                }
                continue;
            } else if (num != 2 && strcmp(buf, "cd") == 0) {
                printf("error,参数不符\n");
                continue;
            }

            if (strcmp(buf, "ls") == 0 && num == 1) { //ls命令
                printf("传输命令ls,是否为绝对路径：%d\n", is_absolute_path(buf1));
                TLV_t->type = 0x02;
                is_find_order = 1;
                TLV_t->length = 0;
                printf("传输命令ls,路径为%s,传输长度为%d%d\n", TLV_t->value, TLV_t->length, TLV_t->seq);
                sendTlv(sockfd,TLV_t);
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv->type==0xFF) {
                    printf("error,接收错误\n");
                } else {
                    printf("%s\n",TLV_recv->value);
                }
                continue;
            } else if (strcmp(buf, "ls") == 0 && num != 1) {
                printf("error,参数不符\n");
                continue;
            }

            if (strcmp(buf, "pwd") == 0 && num==1) { //pwd命令
                printf("传输命令pwd,是否为绝对路径：%d\n", is_absolute_path(buf1));
                TLV_t->type = 0x03;
                is_find_order = 1;
                TLV_t->length = 0;
                printf("传输命令pwd,路径为%s,传输长度为%d\n", TLV_t->value, TLV_t->length);
                sendTlv(sockfd,TLV_t);
                //memset(TLV_t,0,sizeof(TLV_t));
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv->type==0xFF) {
                    printf("error,接收错误\n");
                } else {
                    printf("pwd_type=0x%02X,pwd——recv=%s\n",TLV_recv->type,TLV_recv->value);
                }
                continue;
            } else if (strcmp(buf, "pwd") == 0 && num != 1) {
                printf("error,参数不符\n");
                continue;
            }

            if (strcmp(buf, "puts") == 0 && num == 2) { //puts命令
            if(check_file_hash(sockfd,buf1)==0){
                printf("传输命令puts,上传文件位置为%s,是否为绝对路径：%d\n", buf1, is_absolute_path(buf1));
                printf("请指定服务端文件路径: ");
            char remote_path[1024] = {0};
            fflush(stdout);
            fgets(remote_path, sizeof(remote_path), stdin);
            remote_path[strcspn(remote_path, "\n")] = '\0';
            printf("上传本地文件: %s 到服务端路径: %s\n", buf1, remote_path);
            TLV_t->type = 0x10;
            is_find_order = 1;
            TLV_t->seq = is_absolute_path(remote_path);
            TLV_t->length = (uint32_t)strlen(remote_path);
            strncpy(TLV_t->value, remote_path, sizeof(TLV_t->value) - 1);  // 保留1字节给\0
            TLV_t->value[sizeof(TLV_t->value) - 1] = '\0';
                sendTlv(sockfd,TLV_t);
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv==0xff){
                    printf("禁止上传\n");
                }else{
                    upload_file(sockfd,buf1);

                }
                continue;
            } else if (strcmp(buf, "puts") == 0 && num != 2) {
                printf("error,参数不符\n");
                continue;
            }
        }
            if (strcmp(buf, "gets") == 0 && num == 2) { //gets命令
                is_find_order = 1;
                TLV_t->seq = is_absolute_path(buf1);
                printf("传输命令gets,下载文件位置为%s,是否为绝对路径：%d\n", buf1, is_absolute_path(buf1));
                char local_path[1024] = {0};
            printf("请指定本地保存文件名: ");
            fflush(stdout);
            fgets(local_path, sizeof(local_path), stdin);
            local_path[strcspn(local_path, "\n")] = '\0';
            printf("下载服务端文件: %s 到本地: %s\n", buf1, local_path);
            TLV_t->type = 0x11;
            TLV_t->length = (uint32_t)strlen(buf1);
            strncpy(TLV_t->value, buf1, sizeof(TLV_t->value) - 1);  // 保留1字节给\0
            TLV_t->value[sizeof(TLV_t->value) - 1] = '\0';
            sendTlv(sockfd,TLV_t);
          printf("传输命令gets,路径为%s,传输长度为%d,i是否为绝对路径：%d\n", TLV_t->value, TLV_t->length, TLV_t->seq);
            recvTlv(sockfd,TLV_recv);
            if(TLV_recv->type==0xFF){
                printf("error,接收错误\n");

            }else
            download(sockfd,local_path);
                printf("%s\n",TLV_recv->value);


            continue;
        }
        else if (strcmp(buf, "gets") == 0 && num != 2) {
            printf("error,参数不符\n");
            continue;
        }

            if (strcmp(buf, "remove") == 0 && num == 2) { //remove命令
                printf("传输命令remove,删除位置为%s,是否为绝对路径：%d\n", buf1, is_absolute_path(buf1));
                TLV_t->type = 0x12;
                is_find_order = 1;
                TLV_t->seq = is_absolute_path(buf1);
                TLV_t->length = (uint32_t)strlen(buf1);
                strncpy(TLV_t->value, buf1, sizeof(TLV_t->value) - 1);
                TLV_t->value[sizeof(TLV_t->value) - 1] = '\0';
                printf("传输命令remove,路径为%s,传输长度为%d,i是否为绝对路径：%d\n", TLV_t->value, TLV_t->length, TLV_t->seq);
                sendTlv(sockfd,TLV_t);
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv->type==0xFF) {
                    printf("error,接收错误\n");
                } else {
                    printf("%s\n",TLV_recv->value);
                }
                continue;
            } else if (strcmp(buf, "remove") == 0 && num != 2) {
                printf("error,参数不符\n");
                continue;
            }

            if (strcmp(buf, "mkdir") == 0 && num == 2) { //mkdir命令
                printf("传输命令mkdir,创建位置为%s,是否为绝对路径：%d\n", buf1, is_absolute_path(buf1));
                TLV_t->type = 0x13;
                is_find_order = 1;
                TLV_t->seq = is_absolute_path(buf1);
                TLV_t->length = (uint32_t)strlen(buf1);
                strncpy(TLV_t->value, buf1, sizeof(TLV_t->value) - 1);
                TLV_t->value[sizeof(TLV_t->value) - 1] = '\0';
                printf("传输命令mkdir,路径为%s,传输长度为%d,i是否为绝对路径：%d\n", TLV_t->value, TLV_t->length, TLV_t->seq);
                sendTlv(sockfd,TLV_t);
                printf("CLIENT SEND[type=0x%02X, len=%u, seq=%u, value=%s]\n", 
       TLV_t->type, TLV_t->length, TLV_t->seq, 
        TLV_t->value);
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv->type==0xFF) {
                    printf("error,接收错误\n");
                } else {
                    printf("%s\n",TLV_recv->value);
                }
                continue;
            } else if (strcmp(buf, "mkdir") == 0 && num != 2) {
                printf("error,参数不符\n");
                continue;
            }

            if (strcmp(buf, "rmdir") == 0 && num == 2) { //rmdir命令
                printf("传输命令rmdir,删除位置为%s,是否为绝对路径：%d\n", buf1, is_absolute_path(buf1));
                TLV_t->type = 0x14;
                is_find_order = 1;
                TLV_t->seq = is_absolute_path(buf1);
                TLV_t->length = (uint32_t)strlen(buf1);
                strncpy(TLV_t->value, buf1, sizeof(TLV_t->value) - 1);
                TLV_t->value[sizeof(TLV_t->value) - 1] = '\0';
                printf("传输命令rmdir,路径为%s,传输长度为%d,i是否为绝对路径：%d\n", TLV_t->value, TLV_t->length, TLV_t->seq);
                sendTlv(sockfd,TLV_t);
                recvTlv(sockfd,TLV_recv);
                if(TLV_recv->type==0xFF) {
                    printf("error,接收错误\n");
                } else {
                    printf("%s\n",TLV_recv->value);
                }
                continue;
            } else if (strcmp(buf, "rmdir") == 0 && num != 2) {
                printf("error,参数不符\n");
                continue;
            }

            if (is_find_order == 0) {
                printf("error,未找到命令，请重试\n");
            }
            printf("客户端结束处理命令——————————————————————————————\n");
        } // 命令处理循环结束
    } // 主循环结束

    free(TLV_t);
    free(TLV_recv);
    close(sockfd);
    return 0;
}
